#pragma once


#include<iostream>
#include <memory>
#include<string>
#include<list>
#include<algorithm>
#include<sys/types.h>
#include<sys/socket.h>

#include"Log.hpp"
#include "InetAddr.hpp"
#include"Mutex.hpp"

using namespace LogModule;

//////////////////////////////////////////////////////用户接收模块

//用户行为模块（特指服务端转发对象即用户）
//1.界面
class UserInterface
{
public:
    virtual ~UserInterface() = default;
    virtual void SendTo(int sockfd,const std::string &message) = 0;
    virtual bool operator == (const InetAddr &u) = 0;
    virtual std::string ID() = 0;
};

//2.具体实现
class User : public UserInterface 
{
public:
    User(const InetAddr &id):_id(id)
    {}
    void SendTo(int sockfd,const std::string &message) override
    {
        LOG(LogLevel::DEBUG) << "send message to" << _id.Addr() << "info: " << message;
        int n = ::sendto(sockfd, message.c_str(), message.size(), 0, _id.NetAddr(), _id.NetAddrLen());

    }

    bool operator == (const InetAddr &u) override {return _id == u;}    //通过InetAddr中重载==，利用ip比较
    
    std::string ID() override {return _id.Addr();}

    ~User()
    {}
private:
    InetAddr _id;
};

//对用户消息进行路由(管理用户)
//观察着模式obser(Router)
class UserManger
{
public:
    UserManger(){}

    void AddUser(InetAddr&id)
    {
        LockGuard lockguard(_mutex);
        for(auto &user : _online_user)
        {
            if(*user == id)
            {
                LOG(LogLevel::INFO) << id.Addr() << "用户已经存在" ;
                return;
            }
        }

        LOG(LogLevel::INFO) << id.Addr() << "新增用户" ;
        _online_user.push_back(std::make_shared<User>(id));
        PrintUser();
    }

    void DelUser(InetAddr&id)
    {
        // v1
        auto pos = std::remove_if(_online_user.begin(), _online_user.end(), [&id](std::shared_ptr<UserInterface> &user){
            return *user == id;
        });
        _online_user.erase(pos, _online_user.end());
        PrintUser();

        //v2
        // for(auto user : _online_user)
        // {
        //     if(*user == id)
        //     {
        //         _online_user.erase(user);
        //         break; // 迭代器失效的问题
        //     }
        // }
    }

    //发消息
    void Router(int sockfd,const std::string &message)
    {
        LockGuard lockguard(_mutex);
        for(auto &user :_online_user)
        {
            user->SendTo(sockfd, message);
        }
    }

    void PrintUser()
    {
        for(auto user : _online_user)
        {
            LOG(LogLevel::DEBUG) <<"在线用户-> "<<  user->ID();
        }
    }

    ~UserManger(){}
private:
    std::list<std::shared_ptr<UserInterface>>  _online_user;
    Mutex _mutex;
};